﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Zero.UControl.Base.Helper;

namespace Zero.UControl.Component
{
    /// <summary>
    /// CalendarView.xaml 的交互逻辑
    /// </summary>
    public partial class CalendarView : UserControl
    {
        public ObservableCollection<CalendarDay> Days { get; set; } = new();

        public DateTime CurrentDate
        {
            get { return (DateTime)GetValue(CurrentDateProperty); }
            set { SetValue(CurrentDateProperty, value); }
        }

        public static readonly DependencyProperty CurrentDateProperty =
            DependencyProperty.Register(nameof(CurrentDate), typeof(DateTime), typeof(CalendarView),
                new PropertyMetadata(DateTime.Today));

        public DateTime SelectedDate
        {
            get { return (DateTime)GetValue(SelectedDateProperty); }
            set { SetValue(SelectedDateProperty, value); }
        }

        public static readonly DependencyProperty SelectedDateProperty =
            DependencyProperty.Register("SelectedDate", typeof(DateTime), typeof(CalendarView), new PropertyMetadata(DateTime.Today, OnSelectedDateChanged));

        public static readonly DependencyProperty YearProperty =
            DependencyProperty.Register("Year", typeof(int), typeof(CalendarView),
                new PropertyMetadata(DateTime.Today.Year, OnYearOrMonthChanged));

        public int Year
        {
            get => (int)GetValue(YearProperty);
            set => SetValue(YearProperty, value);
        }

        public static readonly DependencyProperty MonthProperty =
            DependencyProperty.Register("Month", typeof(int), typeof(CalendarView),
                new PropertyMetadata(DateTime.Today.Month, OnYearOrMonthChanged));

        public int Month
        {
            get => (int)GetValue(MonthProperty);
            set => SetValue(MonthProperty, value);
        }

        private static void OnYearOrMonthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is CalendarView view)
            {
                var current = view.SelectedDate;
                var newDate = new DateTime(view.Year, view.Month, 1);
                view.SetValue(SelectedDateProperty, newDate);
            }
        }

        public bool ShowLunar
        {
            get { return (bool)GetValue(ShowLunarProperty); }
            set { SetValue(ShowLunarProperty, value); }
        }

        public static readonly DependencyProperty ShowLunarProperty =
            DependencyProperty.Register("ShowLunar", typeof(bool), typeof(CalendarView), new PropertyMetadata(true));

        public CalendarView()
        {
            InitializeComponent();
            Loaded += CalendarView_Loaded;
            AddHandler(CalendarDayItem.DayClickedEvent,new RoutedEventHandler(ItemClickHandle));
            GenerateDays(SelectedDate);
        }

        private void CalendarView_Loaded(object sender, RoutedEventArgs e)
        {
            MonthSelect.ItemsSource = Enumerable.Range(1, 12).ToList();
            YearSelect.ItemsSource = Enumerable.Range(1970, 100).ToList();
        }

        private void PrevMonth(object sender, RoutedEventArgs e)
        {
            var dt = SelectedDate.AddMonths(-1);
            SetValue(SelectedDateProperty, dt);
            SelectedDate = new DateTime(dt.Year,dt.Month,1);
            SetValue(MonthProperty, dt.Month);
        }

        private void NextMonth(object sender, RoutedEventArgs e)
        {
            var dt = SelectedDate.AddMonths(1);
            SetValue(SelectedDateProperty, SelectedDate.AddMonths(1));
            SelectedDate = new DateTime(dt.Year, dt.Month, 1);
            SetValue(MonthProperty, dt.Month);
        }

        private void ToCurrentDay(object sender, RoutedEventArgs e)
        {
            SetValue(CurrentDateProperty, DateTime.Today);
            SetValue(SelectedDateProperty, DateTime.Today);
            SetValue(YearProperty, DateTime.Now.Year);
            SetValue(MonthProperty, DateTime.Now.Month);
        }

        private void ItemClickHandle(object sender, RoutedEventArgs e)
        {
            var day = e.OriginalSource as CalendarDay;
            if (day == null) return;
            SetValue(SelectedDateProperty, day.Date);
        }

        private static void OnSelectedDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var view = d as CalendarView;
            view.GenerateDays(view.SelectedDate);

            if (view.Days.Count == 0) return;
            foreach (var dayItem in view.Days)
            {
                dayItem.IsSelected = (dayItem.Date == view.SelectedDate);
            }
        }

        private void GenerateDays(DateTime date)
        {
            Days.Clear();

            var firstDay = new DateTime(date.Year, date.Month, 1);
            var daysInMonth = DateTime.DaysInMonth(date.Year, date.Month);
            int offset = ((int)firstDay.DayOfWeek + 6) % 7; // 周一为第一列
            var start = firstDay.AddDays(-offset);

            // 计算本月日历总格数（35 或 42）
            int totalDays = offset + daysInMonth > 35 ? 42 : 35;

            for (int i = 0; i < totalDays; i++)
            {
                var day = start.AddDays(i);
                var lunar = ShowLunar ? LunarHelper.GetLunarText(day) : "";
                var festival = FestivalProvider.GetFestival(day.Month,day.Day);

                var dayItem = new CalendarDay
                {
                    Date = day,
                    Day = day.Day.ToString(),
                    IsToDay = day.Date == DateTime.Today,
                    Lunar = lunar,
                    Festival = festival,
                    IsFestivalDay = FestivalProvider.GetDayTag(day) == "休" ? true : false,
                    IsCurrentMonth = day.Month == date.Month,
                    TagText = FestivalProvider.GetDayTag(day),
                    TagColor = FestivalProvider.GetDayTagColor(day),
                    Foreground = new SolidColorBrush(Color.FromRgb(68, 68, 68)),
                    Background = Brushes.White
                };
              
                if (day.Month != date.Month)
                {
                    dayItem.Foreground = new SolidColorBrush(Color.FromRgb(180, 180, 180));
                    dayItem.Background = new SolidColorBrush(Color.FromRgb(245, 245, 245));
                }
                else if (FestivalProvider.GetDayTag(day) == "休")
                {
                    dayItem.Foreground = new SolidColorBrush(Color.FromRgb(212, 57, 0));
                    dayItem.Background = new SolidColorBrush(Color.FromRgb(253, 247, 244));
                }
                else if (FestivalProvider.GetDayTag(day) == "班")
                {
                    dayItem.Background = new SolidColorBrush(Color.FromRgb(241, 241, 241));
                }

                Days.Add(dayItem);
            }
        }

    }
}
